package com.collection.common.base;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;


import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import com.collection.util.Order;

/**
 * 基类dao实现类
 * @author 冯勇
 *
 * @param <T>
 */
@Repository
public class BaseDaoImpl<T> implements BaseDao<T>{
	
	@Autowired
	protected HibernateTemplate template;
	
	@Autowired
	protected JdbcTemplate jdbcTemplate;
	
	@Autowired
	protected SessionFactory sessionFactory;

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#delete(java.lang.Object)
	 */
	public void delete(T entity) {
		template.delete(entity);
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#get(java.lang.Class, java.io.Serializable)
	 */
	public T get(Class<T> entityClass, Serializable pk) {
		return template.get(entityClass, pk);
	}

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#save(java.lang.Object)
	 */
	public void save(T entity) {
		template.save(entity);
	}

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#update(java.lang.Object)
	 */
	public void update(T entity) {
		template.update(entity);
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#queryByHQL(java.lang.String, java.lang.Object[], int, int)
	 */
	@SuppressWarnings("unchecked")
	public List<T> queryByHQL(final String hql, final Object[] filedValues, final int begin, final int length) {
		return template.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				for (int i = 0; i < filedValues.length; i++)
					query.setParameter(i, filedValues[i]);
				query.setFirstResult(begin);
				query.setMaxResults(length);
				return query.list();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#queryByHQL(java.lang.String, java.lang.Object[])
	 */
	@SuppressWarnings("unchecked")
	public List<T> queryByHQL(String hql, Object[] paramsValues) {
		return template.find(hql, paramsValues);
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#queryByHQL(java.lang.String, java.lang.Object[], int, int, net.wlsj.util.Order)
	 */
	public List<T> queryByHQL(String hql, Object[] paramsValues, int begin,
			int length, Order order) {
		if(order != null) {
			hql += " order by " + order.getFiledName() + (order.isDesc() ? " desc " : " asc ");
		}
		return queryByHQL(hql, paramsValues, begin, length);
	}

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#queryByHQL(java.lang.String, java.lang.Object[], net.wlsj.util.Order)
	 */
	public List<T> queryByHQL(String hql, Object[] paramsValues, Order order) {
		if(order != null) {
			hql += " order by " + order.getFiledName() + (order.isDesc() ? " desc " : " asc ");
		}
		return queryByHQL(hql, paramsValues);
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#queryByHQL(java.lang.String, int, int)
	 */
	@SuppressWarnings("unchecked")
	public List<T> queryByHQL(final String hql, final int begin, final int length) {
		return template.executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setFirstResult(begin);
				query.setMaxResults(length);
				return query.list();
			}
		});
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#queryByHQL(java.lang.String, int, int, net.wlsj.util.Order)
	 */
	public List<T> queryByHQL(String hql, final int begin, final int length, Order order) {
		if(order != null) {
			hql += " order by " + order.getFiledName() + (order.isDesc() ? " desc " : " asc ");
		}
		return queryByHQL(hql, begin, length);
	}

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#queryByHQL(java.lang.String)
	 */
	@SuppressWarnings("unchecked")
	public List<T> queryByHQL(String hql) {
		return template.find(hql);
	}

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#getRecordCount(java.lang.String, java.lang.Object[])
	 */
	public int getRecordCount(String hql, Object[] paramValues) {
		return Integer.parseInt(template.find(hql, paramValues).get(0).toString());
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#getRecordCount(java.lang.String)
	 */
	public int getRecordCount(String hql) {
		return Integer.parseInt(template.find(hql).get(0).toString());
	}

	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#clear(java.lang.Class)
	 */
	public void clear(Class<T> entityClass) {
		template.bulkUpdate("delete from " + entityClass.getName());
	}
	
	/*
	 * (non-Javadoc)
	 * @see net.wlsj.common.base.BaseDao#deleteByHQL(java.lang.String)
	 */
	public void deleteByHQL(String hql) {
		template.bulkUpdate(hql);
	}

	public HibernateTemplate getTemplate() {
		return template;
	}

	public void setTemplate(HibernateTemplate template) {
		this.template = template;
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
}
